package com.zmn.oms.third.baidu_mall.service.impl;

import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.query.ChannelQuery;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.oms.business.impl.messageV1.ZmnMcsSendUtil;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.messageV1.DingTalkMessageDIO;
import com.zmn.oms.model.dto.messageV1.SendMscDIO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.order.proxy.CreateOrderDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.third.baidu_mall.BaiduMallConsts;
import com.zmn.oms.third.baidu_mall.BaiduMallMapper;
import com.zmn.oms.third.baidu_mall.dto.TextOrderInfo;
import com.zmn.oms.third.baidu_mall.service.BaiduMallService;
import com.zmn.oms.third.base.util.ThirdOrderUtil;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.pay.gateway.common.constants.PayStatusConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 类描述：
 *
 * @author LiangHailong
 * @date 2021/06/17 15:05
 */
@Slf4j
@Service("baiduMallService")
public class BaiduMallServiceImpl implements BaiduMallService {

    private static final Pattern ORDER_INFO_PATTERN = Pattern.compile("用户[【|\\[](\\d+)[】|\\]]已支付\\s?\\{?(\\d+)\\}?\\s?件[【|\\[](.*?)[】|\\]]的预约金(\\d+)元\\s?，\\s?预约服务时间为『(.*?)』预约服务地址[【|\\[](.*?)[;|；]\\s?收货人：(.*?)[;|；]\\s?电话：(\\d+)[;|；][】|\\]]，");

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected AreaListRemoteService areaListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected ChannelListRemoteService channelListRemoteService;

    @Autowired
    private ProxyOrderBService proxyOrderBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private BaiduMapBService baiduMapBService;

    @Override
    public void procMsg(String baiduMsg, Integer channelId) throws OmsBaseException {

        OrderWork orderWork = null;
        try {
            CreateOrderDTO zmnOrder = buildOrderDTO(baiduMsg, channelId);
            OrderBO orderBO = proxyOrderBService.createOrder(zmnOrder);
            orderWork = orderBO.getOrderWork();
        } catch (OmsBaseException e) {
            log.error(e.getMessage(), e);

            log.info("【{}-消息-订单】保存订单失败，发送钉钉消息：{}", BaiduMallConsts.NAME, baiduMsg);
            sendDingTalkMessageOnFailed(baiduMsg, channelId);
            return;
        }

        log.info("【{}-消息-订单】保存订单成功 OrderId:[{}]", BaiduMallConsts.NAME, orderWork.getOrderId());

        try {
            // 工单自动流转
            workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }




    private CreateOrderDTO buildOrderDTO(String baiduMsg, Integer channelId) throws OmsBaseException {
        CreateOrderDTO zmnOrder = new CreateOrderDTO();
        zmnOrder.setChannelId(channelId);
        zmnOrder.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        zmnOrder.setGender(GlobalDict.GENDER_NO);
        zmnOrder.setDisableDiscard(GlobalConsts.NO);
        zmnOrder.setOperator("系统");
        zmnOrder.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        zmnOrder.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        zmnOrder.setInputType(OrderConsts.ORDER_INPUT_TYPE_API);

        {
            TextOrderInfo orderInfo = _parseOrderInfo(baiduMsg);

            zmnOrder.setContactName(orderInfo.getContactName());
            zmnOrder.setTelephone(orderInfo.getContactPhone());

            _fillProductInfo(zmnOrder, orderInfo);
            _fillAddress(zmnOrder, orderInfo);
            _fillDutyTime(zmnOrder, orderInfo);
            _fillPrepayAmount(zmnOrder, orderInfo);
        }

        zmnOrder.setOperatorLogRemark(baiduMsg);

        return zmnOrder;
    }

    private TextOrderInfo _parseOrderInfo(String baiduMsg) throws OmsBaseException {
        Matcher matcher = ORDER_INFO_PATTERN.matcher(baiduMsg);
        if (matcher.find()) {
            TextOrderInfo orderInfo = new TextOrderInfo();
            orderInfo.setUserId(matcher.group(1));
            orderInfo.setProductNumber(matcher.group(2));
            orderInfo.setProductName(matcher.group(3));
            orderInfo.setBill(matcher.group(4));
            orderInfo.setDutyTime(matcher.group(5));
            orderInfo.setAddress(matcher.group(6));
            orderInfo.setContactName(matcher.group(7));
            orderInfo.setContactPhone(matcher.group(8));

            return orderInfo;
        }
        else {
            throw new OmsBaseException("解析订单信息失败");
        }
    }

    /**
     * 补全产品信息
     * @param zmnOrder
     * @param orderInfo
     */
    private void _fillProductInfo(CreateOrderDTO zmnOrder, TextOrderInfo orderInfo) {
        OrderProductDTO orderProduct = new OrderProductDTO();
        orderProduct.setProductId(BaiduMallMapper.getProductId(orderInfo.getProductName()));
        orderProduct.setNumber(Integer.parseInt(orderInfo.getProductNumber()));
        zmnOrder.setOrderProductList(Arrays.asList(orderProduct));
    }

    /**
     * 补全订单地址：将地址转换成符合我们自己系统使用的地址信息
     * @param zmnOrder
     * @param orderInfo
     */
    private void _fillAddress(CreateOrderDTO zmnOrder, TextOrderInfo orderInfo)  {
        // 去掉空格和括号
        Pattern pattern = Pattern.compile("\\s+|（.*）|[(](.*)[)]");
        Matcher matcher = pattern.matcher(orderInfo.getAddress());
        String buyerAddress = matcher.replaceAll("");

        // 具体地址放入address
        zmnOrder.setAddress(buyerAddress);
        zmnOrder.setStreet(""); // street字段在数据库中不能为空

        LngLatLocation location = baiduMapBService.location(buyerAddress);
        if (location != null) {
            Double lng = Double.valueOf(location.getLng());
            Double lat = Double.valueOf(location.getLat());

            try {
                Optional.ofNullable(areaListRemoteService.getAreaByLatAndLng(lng, lat))
                        .map(ResponseDTO::getData)
                        .ifPresent(areaDRO -> {
                            zmnOrder.setCityId(areaDRO.getParentId());
                            zmnOrder.setLatitude(lat);
                            zmnOrder.setLongitude(lng);
                        });
            } catch (Exception e) {
                log.error("【{}-消息-订单】使用经纬度获取CityId失败:[{}]", BaiduMallConsts.NAME, e.getMessage(), e);
            }
        }
    }

    /**
     * 预付款
     * @param zmnOrder
     * @param orderInfo
     */
    private void _fillPrepayAmount(CreateOrderDTO zmnOrder, TextOrderInfo orderInfo) {
        int prepayAmount = NumberUtil.convertMoneyToFen(orderInfo.getBill());
        if (prepayAmount > 0) {
            zmnOrder.setChannelPrepayAmount(prepayAmount);
            zmnOrder.setChannelPrepayStatus(PayStatusConsts.PAY_STATUS_SUCCESS);
        }
    }

    /**
     * 预约时间
     * @param orderDTO
     * @param orderInfo
     */
    private void _fillDutyTime(CreateOrderDTO orderDTO, TextOrderInfo orderInfo) {
        Date dutyTime = null;

        if (StringUtils.isNotBlank(orderInfo.getDutyTime())) {
            dutyTime = DateUtil.parse(orderInfo.getDutyTime(), DateUtil.FORMAT_DEFAULT);
        }
        if (dutyTime == null) {
            dutyTime = ThirdOrderUtil.getDefaultDutyTime();
        }

        orderDTO.setDutyTime(dutyTime);
    }

    private void sendDingTalkMessageOnFailed(String content, Integer channelId) {
        if (BaiduMallConsts.MSG_RULE_ID == null || BaiduMallConsts.DINGTALK_ID_FOR_RECIVE_MSG == null) {
            log.info("Send DingTalkMessage failed! BaiduMallConsts.MSG_RULE_ID=[{}], BaiduMallConsts.DINGTALK_ID_FOR_RECIVE_MSG=[{}]",
                    BaiduMallConsts.MSG_RULE_ID, BaiduMallConsts.DINGTALK_ID_FOR_RECIVE_MSG);
            return;
        }
        SendMscDIO sendMscDIO = new SendMscDIO();
        sendMscDIO.setRuleId(BaiduMallConsts.MSG_RULE_ID);// 消息ID：线上场景ID：10389，test2场景ID：10449
        DingTalkMessageDIO dingTaikParams = new DingTalkMessageDIO();
        sendMscDIO.setDingTalkParams(dingTaikParams);

        ChannelQuery channelQuery = new ChannelQuery();
        channelQuery.setChannelId(channelId);
        String channelName = Optional.ofNullable(channelListRemoteService.listByQuery(channelQuery))
                .map(ResponseDTO::getData)
                .map(list -> list.isEmpty() ? null : list.get(0))
                .map(ChannelDRO::getName)
                .map(name -> StringUtils.isBlank(name) ? null : name)
                .orElse(BaiduMallConsts.NAME);


        dingTaikParams.setDingTalkId(BaiduMallConsts.DINGTALK_ID_FOR_RECIVE_MSG); // 员工钉钉ID
        dingTaikParams.setParams(
                String.format("{\"msg_content\":\"渠道ID：%s；渠道名称：%s；录单内容：%s\"}",
                channelId.toString(), channelName, content)
        );

        ZmnMcsSendUtil.send(sendMscDIO);
    }
}
